/**
 * 验证工具类
 * @author jaylen
 */
import { TuniaoInnerColors, TuniaoInnerColor } from '../types/tuniao-ui'

/**
 * 验证电子邮箱格式
 */
export const email = (value: string): boolean => {
	return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test(value)
}

/**
 * 验证手机格式
 */
export const mobile = (value: string): boolean => {
	return /^1[3-9]\d{9}$/.test(value)
}

/**
 * 验证URL格式
 */
export const url = (value: string): boolean => {
	return /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/.test(value)
}

/**
 * 验证日期格式
 */
export const date = (value: string): boolean => {
	return !/Invalid|NaN/.test(new Date(value).toString())
}

/**
 * 验证ISO类型的日期格式
 */
export const dateISO = (value: string): boolean => {
	return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
}

/**
 * 验证十进制数字
 */
export const number = (value: string): boolean => {
	return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
}

/**
 * 验证整数
 */
export const digits = (value: string): boolean => {
	return /^\d+$/.test(value)
}

/**
 * 验证身份证号码
 */
export const idCard = (value: string): boolean => {
	return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
		value)
}

/**
 * 是否车牌号
 */
export const carNo = (value: string): boolean => {
	// 新能源车牌
	const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
	// 旧车牌
	const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
	if (value.length === 7) {
		return creg.test(value)
	} else if (value.length === 8) {
		return xreg.test(value)
	} else {
		return false
	}
}

/**
 * 金额,只允许2位小数
 */
export const amount = (value: string): boolean => {
	//金额，只允许保留两位小数
	return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
}

/**
 * 中文
 */
export const chinese = (value: string): boolean => {
	let reg = /^[\u4e00-\u9fa5]+$/gi
	return reg.test(value)
}

/**
 * 只能输入字母
 */
export const letter = (value: string): boolean => {
	return /^[a-zA-Z]*$/.test(value)
}

/**
 * 只能是字母或者数字
 */
export const enOrNum = (value: string): boolean => {
	//英文或者数字
	let reg = /^[0-9a-zA-Z]*$/g
	return reg.test(value)
}

/**
 * 验证是否包含某个值
 */
export const contains = (value: string, param: string): boolean => {
	return value.indexOf(param) >= 0
}

/**
 * 验证一个值范围[min, max]
 */
export const range = (value: string|number, param: (string|number)[]): boolean => {
	return value >= param[0] && value <= param[1]
}

/**
 * 验证一个长度范围[min, max]
 */
export const rangeLength = (value:  string, param: (string|number)[]): boolean => {
	return value.length >= param[0] && value.length <= param[1]
}

/**
 * 是否固定电话
 */
export const landline = (value: string): boolean => {
	let reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
	return reg.test(value)
}

/**
 * 判断是否为空
 */
export const empty = (value: any): boolean => {
	switch (typeof value) {
		case 'undefined':
			return true
		case 'string':
			if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
			break
		case 'boolean':
			if (!value) return true
			break
		case 'number':
			if (0 === value || isNaN(value)) return true
			break
		case 'object':
			if (null === value) return true
			for (var i in value) {
				return false
			}
			return true
	}
	return false
}

/**
 * 是否json字符串
 */
export const jsonString = (value: string): boolean => {
	if (typeof value == 'string') {
		try {
			var obj = JSON.parse(value)
			if (typeof obj == 'object' && obj) {
				return true
			} else {
				return false
			}
		} catch (e) {
			return false
		}
	}
	return false
}


/**
 * 是否数组
 */
export const array = (value: any): boolean => {
	if (typeof Array.isArray === "function") {
		return Array.isArray(value);
	} else {
		return Object.prototype.toString.call(value) === "[object Array]"
	}
}

/**
 * 是否对象
 */
export const object = (value: any): boolean => {
	return Object.prototype.toString.call(value) === '[object Object]'
}

/**
 * 是否短信验证码
 */
export const code = (value: string, len: number = 6): boolean => {
	return new RegExp(`^\\d{${len}}$`).test(value)
}

/**
 * 检验尺寸类型的值是否正确
 * @param value 待进行校验的值
 * @returns 校验结果
 */
export const validatorSizeValue = (value: string | number): boolean => {
	if (!value || value === 'auto') return true
  if (typeof value === 'number') {
    return /^(\d?|[1-9]\d+?)(\.\d+)?$/.test(String(value))
  }
  return /^(((\d*?(\.\d+)?)((rpx)|(px)))|((100|[1-9]?\d(\.\d+)?)%)|((\d?|[1-9]\d+?)(\.\d+)?))$/.test(value)
}

/**
 * 验证颜色值格式是否正确
 * @param type 验证颜色类型
 * @param value 颜色的值
 * @returns 验证是否通过
 */
export const validatorColorValue = (type: 'color' | 'bg' | 'shadow' | 'border', value: string, checkInner: boolean = true): boolean => {
  // 如果为空则默认返回验证通过
  if (!value) {
    return true
  }
  const ColorReg: RegExp = /^(#(([a-fA-F0-9]{8})|([a-fA-F0-9]{6})|([a-fA-F0-9]{3})))|((rgb|RGB)\(((0?\d?|1\d{0,2}|2[0-5]{2}),){2}(0?\d?|1\d{0,2}|2[0-5]{2})\))|((rgba|RGBA)\(((0?\d?|1\d{0,2}|2[0-5]{2}),){3}(0\.[0-9][1-9]{0,1})\))$/
  // 验证是否为十六进制或者为rgb、rgba模式的颜色值
  if (ColorReg.test(value)) {
    return true
  }

	// css内置的颜色
	const CSSInnerColors = ['aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon', 'navy', 'olive', 'orange', 'purple', 'red', 'silver', 'teal', 'white', 'yellow'] as const
	type CSSInnerColor = typeof CSSInnerColors[number]

	if (CSSInnerColors.includes(value as CSSInnerColor)) {
		return true
	}

	// 验证内部颜色
	if (checkInner) {
		// 验证是否使用了内部类作为颜色值
		if (type === 'color' || type === 'shadow' || type === 'border') {
			return TuniaoInnerColors.includes(value.replace(`tn-${type}-`, '') as TuniaoInnerColor)
		}
		if (type === 'bg') {
			const bgReg: RegExp = new RegExp(`^tn-(bg)|(dynamic-bg)|(cool-bg)`)
			return value === 'transparent' || TuniaoInnerColors.includes(value.replace('tn-bg-', '') as TuniaoInnerColor) || bgReg.test(value)
		}
	}
  return false
}

/**
 * 验证带透明度的颜色时候正确
 * @param value 颜色值
 * @returns 校验结果
 */
export const validatorTransparentColor = (value: string) => {
	// 如果为空则默认返回验证通过
  if (!value) {
    return true
  }
	const ColorReg: RegExp = /^(#(([a-fA-F0-9]{8})))|((rgba|RGBA)\(((0?\d?|1\d{0,2}|2[0-5]{2}),){3}(0\.[0-9][1-9]{0,1})\))$/
	// 验证是否为8位十六进制或者为rgba模式的颜色值
  if (ColorReg.test(value)) {
    return true
  }

	return false
}